use std::sync::Arc;
use tokio::sync::Mutex;
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
use lazy_static::lazy_static;
use tauri::{AppHandle, Emitter};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HttpSettings {
    pub http_proxy: String,
    pub http_proxy_user: String,
    pub http_proxy_passwd: String,
    pub https_proxy: String,
    pub https_proxy_user: String,
    pub https_proxy_passwd: String,
    pub user_agent: String,
    pub custom_headers: String,
    pub check_certificate: bool,
    pub http_accept_gzip: bool,
    pub http_auth_challenge: bool,
    pub http_pipelining: bool,
}

// 下载任务的状态
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum DownloadStatus {
    Pending,
    Downloading,
    Paused,
    Completed,
    Error,
}

// 线程进度信息
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ThreadProgress {
    pub thread_id: u32,
    pub start_pos: u64,
    pub end_pos: u64,
    pub current_pos: u64,
}

// 下载进度信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DownloadProgress {
    pub total_size: u64,
    pub downloaded_size: u64,
    pub progress: f64,
    pub status: DownloadStatus,
    pub thread_progress: Vec<ThreadProgress>,
}

// 下载任务
pub struct DownloadTask {
    pub id: u32,
    pub url: String,
    pub file_name: String,
    pub path: String,
    pub protocol: String,  // "http", "ftp" or "sftp"
    pub progress: Arc<tokio::sync::RwLock<DownloadProgress>>,
    pub cancel_flag: Arc<tokio::sync::RwLock<bool>>,
}

// 下载管理器
pub struct DownloadManager {
    pub tasks: Arc<Mutex<HashMap<u32, Arc<DownloadTask>>>>,
    pub settings: Arc<tokio::sync::RwLock<HttpSettings>>,
}

lazy_static! {
    pub static ref DOWNLOAD_MANAGER: DownloadManager = DownloadManager {
        tasks: Arc::new(Mutex::new(HashMap::new())),
        settings: Arc::new(tokio::sync::RwLock::new(HttpSettings {
            http_proxy: String::new(),
            http_proxy_user: String::new(),
            http_proxy_passwd: String::new(),
            https_proxy: String::new(),
            https_proxy_user: String::new(),
            https_proxy_passwd: String::new(),
            user_agent: String::new(),
            custom_headers: String::new(),
            check_certificate: true,
            http_accept_gzip: true,
            http_auth_challenge: true,
            http_pipelining: true,
        })),
    };
}

impl DownloadManager {
    pub async fn add_task(
        &self,
        id: u32,
        url: String,
        file: String,
        path: String,
    ) -> Result<(), String> {
        let protocol = if url.starts_with("sftp://") {
            "sftp"
        } else if url.starts_with("ftp://") {
            "ftp"
        } else if url.starts_with("http://") || url.starts_with("https://") {
            "http"
        } else if url.starts_with("magnet:") {
            "magnet"
        } else if url.ends_with(".torrent") {
            "torrent"
        } else {
            return Err("不支持的协议".to_string());
        };

        let task = Arc::new(DownloadTask {
            id,
            url,
            file_name: file,
            path,
            protocol: protocol.to_string(),
            progress: Arc::new(tokio::sync::RwLock::new(DownloadProgress {
                total_size: 0,
                downloaded_size: 0,
                progress: 0.0,
                status: DownloadStatus::Pending,
                thread_progress: Vec::new(),
            })),
            cancel_flag: Arc::new(tokio::sync::RwLock::new(false)),
        });

        let mut tasks = self.tasks.lock().await;
        tasks.insert(id, task);
        Ok(())
    }

    pub async fn restore_task(
        &self,
        id: u32,
        url: String,
        file: String,
        path: String,
        thread_progress: Vec<ThreadProgress>,
    ) -> Result<(), String> {
        let protocol = if url.starts_with("sftp://") {
            "sftp"
        } else if url.starts_with("ftp://") {
            "ftp"
        } else if url.starts_with("http://") || url.starts_with("https://") {
            "http"
        } else {
            return Err("不支持的协议".to_string());
        };

        let total_size = thread_progress.iter().map(|tp| tp.end_pos).max().unwrap_or(0);
        let downloaded_size = thread_progress.iter().map(|tp| tp.current_pos - tp.start_pos).sum();

        let task = Arc::new(DownloadTask {
            id,
            url,
            file_name: file,
            path,
            protocol: protocol.to_string(),
            progress: Arc::new(tokio::sync::RwLock::new(DownloadProgress {
                total_size,
                downloaded_size,
                progress: if total_size > 0 {
                    (downloaded_size as f64 / total_size as f64) * 100.0
                } else {
                    0.0
                },
                status: DownloadStatus::Paused,
                thread_progress,
            })),
            cancel_flag: Arc::new(tokio::sync::RwLock::new(false)),
        });

        let mut tasks = self.tasks.lock().await;
        tasks.insert(id, task);
        Ok(())
    }
}

// 创建下载任务
#[tauri::command]
pub async fn create_download_task(
    id: u32,
    url: String,
    file: String,
    path: String,
) -> Result<String, String> {
    use std::path::Path;

    // 检查文件路径的父目录是否存在
    let p_path = Path::new(&path);
    if !p_path.exists() {
        return Err("目录不存在".to_string());
    }
    if !p_path.is_dir() {
        return Err("指定路径不是目录".to_string());
    }

    // 添加任务并处理可能的错误
    match DOWNLOAD_MANAGER.add_task(id, url, file, path).await {
        Ok(_) => Ok("任务创建成功".to_string()),
        Err(e) => Err(e),
    }
}

// 开始下载任务
#[tauri::command]
pub async fn start_download(
    app_handle: AppHandle,
    id: u32,
) -> Result<String, String> {
    let tasks = DOWNLOAD_MANAGER.tasks.lock().await;
    let task = tasks.get(&id).ok_or(format!("找不到下载任务 {}", id))?.clone();
    drop(tasks);

    // 根据协议选择下载方式
    let app_handle_clone = app_handle.clone();
    let task_clone = task.clone();
    tokio::spawn(async move {
        let result = match task_clone.protocol.as_str() {
            "http" => crate::my_http::download_with_threads(app_handle_clone.clone(), task_clone.clone(), true).await,
            "ftp" => crate::my_ftp::download_ftp(app_handle_clone.clone(), task_clone.clone()).await,
            "sftp" => crate::my_ftp::download_sftp(app_handle_clone.clone(), task_clone.clone()).await,
            "magnet" => crate::my_torrent::download_magnet(app_handle_clone.clone(), task_clone.clone()).await,
            "torrent" => crate::my_torrent::download_torrent(app_handle_clone.clone(), task_clone.clone(), task_clone.url.clone()).await,
            _ => Err("不支持的协议".to_string()),
        };

        if let Err(e) = result {
            println!("下载失败: {}", e);
            let mut progress = task_clone.progress.write().await;
            progress.status = DownloadStatus::Error;
            let progress_clone = progress.clone();
            drop(progress);
            if let Err(e) = app_handle_clone.emit("download_progress", progress_clone) {
                println!("发送错误状态失败: {}", e);
            }
        }
    });

    Ok("任务已开始下载".to_string())
}

// 暂停下载
#[tauri::command]
pub async fn pause_download(app_handle: AppHandle, id: u32) -> Result<(), String> {
    let tasks = DOWNLOAD_MANAGER.tasks.lock().await;

    if let Some(task) = tasks.get(&id) {
        let mut cancel_flag = task.cancel_flag.write().await;
        *cancel_flag = true;

        let mut progress = task.progress.write().await;
        progress.status = DownloadStatus::Paused;

        let progress_clone = progress.clone();
        drop(progress);
        app_handle
            .emit("download_progress", progress_clone)
            .map_err(|e| e.to_string())?;

        Ok(())
    } else {
        Err(format!("找不到下载任务 {}", id))
    }
}

// 恢复下载
#[tauri::command]
pub async fn resume_download(app_handle: AppHandle, id: u32) -> Result<(), String> {
    let tasks = DOWNLOAD_MANAGER.tasks.lock().await;

    if let Some(task) = tasks.get(&id) {
        let task = task.clone();
        {
            let mut cancel_flag = task.cancel_flag.write().await;
            *cancel_flag = false;
        }

        {
            let mut progress = task.progress.write().await;
            progress.status = DownloadStatus::Pending;
            let progress_clone = progress.clone();
            drop(progress);
            app_handle
                .emit("download_progress", progress_clone)
                .map_err(|e| e.to_string())?;
        }

        let app_handle = app_handle.clone();
        tokio::spawn(async move {
            let result = match task.protocol.as_str() {
                "ftp" => crate::my_ftp::download_ftp(app_handle.clone(), task.clone()).await,
                "sftp" => crate::my_ftp::download_sftp(app_handle.clone(), task.clone()).await,
                "http" => crate::my_http::download_with_threads(app_handle.clone(), task.clone(), true).await,
                "magnet" => crate::my_torrent::download_magnet(app_handle.clone(), task.clone()).await,
                "torrent" => crate::my_torrent::download_torrent(app_handle.clone(), task.clone(), task.url.clone()).await,
                _ => Err("不支持的协议".to_string()),
            };

            if let Err(e) = result {
                println!("恢复下载失败: {}", e);
            }
        });

        Ok(())
    } else {
        Err(format!("找不到下载任务 {}", id))
    }
}

// 删除下载任务
#[tauri::command]
pub async fn delete_download(id: u32) -> Result<(), String> {
    let mut tasks = DOWNLOAD_MANAGER.tasks.lock().await;

    if !tasks.contains_key(&id) {
        return Err(format!("找不到下载任务 {}", id));
    }

    if let Some(task) = tasks.get(&id) {
        let mut cancel_flag = task.cancel_flag.write().await;
        *cancel_flag = true;
    }

    tasks.remove(&id);
    Ok(())
}